package org.jeecg.modules.dock.handler.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.plant.service.IWmsSapWarehouseMapService;
import org.jeecg.modules.basic.unit.service.IBasicUnitService;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTaskMaterial;
import org.jeecg.modules.business.warehouse.entity.vo.WmsInReceiptTaskPage;
import org.jeecg.modules.dock.constant.MaterialTypeConstants;
import org.jeecg.modules.dock.constant.SystemConstants;
import org.jeecg.modules.dock.entity.dto.request.OutsourcingPurchaseOrderRequestDTO;
import org.jeecg.modules.dock.entity.dto.response.SapBaseResponseDTO;
import org.jeecg.modules.dock.enums.*;
import org.jeecg.modules.dock.handler.AbstractSapDataHandler;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 外购采购订单主数据handler
 *
 * @author zhoutong
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class OutsourcingPurchaseOrderHandler extends AbstractSapDataHandler<OutsourcingPurchaseOrderRequestDTO> {

    private final WorkFlowService workFlowService;
    private final IBasicMaterialService materialService;
    private final IBasicUnitService iBasicUnitService;
    private final SapCommonService sapCommonService;
    private final IWmsSapWarehouseMapService wmsSapWarehouseMapService;
    @Value(value = "${wms.config.personnel.sap:}")
    private String personnelSap;

    /**
     * 入库任务-物料赋值
     *
     * @param dto
     * @return
     */
    @NotNull
    private static WmsInReceiptTaskMaterial setValue(OutsourcingPurchaseOrderRequestDTO dto) {
        WmsInReceiptTaskMaterial material = new WmsInReceiptTaskMaterial();
        material.setOriginalSystemNumber(dto.getProcurementVoucherCode());
        material.setOriginalSystemLineNumber(dto.getProcurementVoucherProjectCode().toString());
        return material;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized List<? extends SapBaseResponseDTO> doHandle(List<OutsourcingPurchaseOrderRequestDTO> data) {
        List<SapBaseResponseDTO> list = new ArrayList<>(16);
        log.info("收到外购采购订单主数据发货:{},\n共{}条", data, data.size());
        if (CollectionUtil.isNotEmpty(data)) {

            List<String> materialCodes = data.stream().map(t -> t.getMaterialCode()).collect(Collectors.toList());
            sapCommonService.verifyExistenceMaterialCode(materialCodes);

            List<WmsInReceiptTaskMaterial> result = new ArrayList<>(16);
            String materialType = data.get(0).getMaterialType();

            Map<String, String> unitIdMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(data)) {
                List<String> codes = data.stream().map(t -> t.getUnit()).collect(Collectors.toList());
                unitIdMap = iBasicUnitService.getIdByCodes(codes);
            }
            for (OutsourcingPurchaseOrderRequestDTO dto : data) {
                WmsInReceiptTaskMaterial material = new WmsInReceiptTaskMaterial();
                material.setSaleOrderNumber(dto.getSaleOrder());
                if (StringUtils.isNotBlank(dto.getSaleOrder())) {
                    material.setSaleOrderLineNumber(dto.getSaleOrderLineNumber().toString());
                }
                material.setProductNumber(dto.getProductOrder());
                material.setOriginalSystemNumber(dto.getProcurementVoucherCode());
                material.setOriginalSystemLineNumber(String.valueOf(dto.getProcurementVoucherProjectCode()));
                material.setExtraText(JSON.toJSONString(dto));
                material.setFactory(dto.getFactory());
                if (ObjectUtil.isNotNull(dto.getProcurementOrderQuantity())) {
                    material.setPlanQuantity(dto.getProcurementOrderQuantity());
                }
                if (ObjectUtil.isNotEmpty(unitIdMap.get(dto.getUnit()))) {
                    material.setWmsBasicUnitId(unitIdMap.get(dto.getUnit()));
                }
                BasicMaterial basicMaterial = materialService.getOne(new LambdaQueryWrapper<BasicMaterial>().eq(BasicMaterial::getCode, dto.getMaterialCode()).last("limit 1"));
                if (ObjectUtil.isNotEmpty(basicMaterial)) {
                    material.setWmsBasicMaterialId(basicMaterial.getId());
                    if (StringUtils.isNotEmpty(basicMaterial.getAssistantUnitId())) {
                        material.setUnitAssistId(basicMaterial.getAssistantUnitId());
                        material.setAssistQuantity(BigDecimal.ONE);
                    }
                }
                // 根据仓库code查询仓库ID
                String wmsBasicWarehouseId = wmsSapWarehouseMapService.getWmsStroeBySapStore(dto.getStoreLocation(),dto.getFactory());
                material.setWmsBasicWarehouseId(wmsBasicWarehouseId);
                if (wmsBasicWarehouseId == null){
                    material.setSapLocationFactory(dto.getStoreLocation()+"-"+dto.getFactory());
                    material.setWmsBasicWarehouseId("");
                }
                material.setSapLocation(dto.getStoreLocation());
                result.add(material);
            }
            WmsInReceiptTaskPage wmsInReceiptTaskPage = new WmsInReceiptTaskPage();
            wmsInReceiptTaskPage.setOrganization("A04A01");
            BaseFlowDto baseFlowDto = new BaseFlowDto();
            // 判断物料类型, 根据物料类型来处理单据
            if (materialType.equals(MaterialTypeConstants.PT01)) {
                wmsInReceiptTaskPage.setDocumentType(ReceiptsEnum.R01.getCode());
                baseFlowDto.setDocumentType(ReceiptsEnum.R01.getCode());
                baseFlowDto.setCode(ReceiptsEnum.R01.getRemark());
            } else if (materialType.equals(MaterialTypeConstants.PT02)) {
                wmsInReceiptTaskPage.setDocumentType(ReceiptsEnum.R24.getCode());
                baseFlowDto.setDocumentType(ReceiptsEnum.R24.getCode());
                baseFlowDto.setCode(ReceiptsEnum.R24.getRemark());
            } else if (materialType.equals(MaterialTypeConstants.PT04)) {
                wmsInReceiptTaskPage.setDocumentType(ReceiptsEnum.R53.getCode());
                baseFlowDto.setDocumentType(ReceiptsEnum.R53.getCode());
                baseFlowDto.setCode(ReceiptsEnum.R53.getRemark());
            } else if (materialType.equals(MaterialTypeConstants.PT06)) {
                wmsInReceiptTaskPage.setDocumentType(ReceiptsEnum.R24.getCode());
                baseFlowDto.setDocumentType(ReceiptsEnum.R24.getCode());
                baseFlowDto.setCode(ReceiptsEnum.R24.getRemark());
            }
            wmsInReceiptTaskPage.setSysOrgCode("A04A01");
            wmsInReceiptTaskPage.setOwnerType("1");
            wmsInReceiptTaskPage.setOwner("A05");
            wmsInReceiptTaskPage.setOriginalSystem(SystemConstants.SAP);
            wmsInReceiptTaskPage.setWmsInReceiptTaskMaterialList(result);
            wmsInReceiptTaskPage.setDocumentCode(FillRuleUtil.executeRule(DirectionOfInventoryEnum.STORAGE.getCode(), JSON.parseObject(DirectionOfInventoryEnum.STORAGE.getRemark())).toString());
            wmsInReceiptTaskPage.setTaskDate(DateUtil.parseDate(DateUtil.now()));
            wmsInReceiptTaskPage.setRequestTime(new Date());
            wmsInReceiptTaskPage.setCreateBy(personnelSap);

            if (CollectionUtil.isNotEmpty(wmsInReceiptTaskPage.getWmsInReceiptTaskMaterialList())) {
                WmsInReceiptTaskMaterial taskMaterial = wmsInReceiptTaskPage.getWmsInReceiptTaskMaterialList().get(0);
                wmsInReceiptTaskPage.setOriginalSystemNumber(taskMaterial.getOriginalSystemNumber());
            }
            wmsInReceiptTaskPage.setRequestPerson(DirectionOfInventoryEnum.STORAGE.getSource());
            wmsInReceiptTaskPage.setCreateBy(DirectionOfInventoryEnum.STORAGE.getSource());
            baseFlowDto.setBusinessType(BusinessTypeEnum.document_task.name());
            baseFlowDto.setData(wmsInReceiptTaskPage);
            SapBaseResponseDTO sapBaseResponseDTO = new SapBaseResponseDTO();
            try {
                workFlowService.commit(baseFlowDto);
                sapBaseResponseDTO.setResult(DockDataStatus.SUCCESS.getCode());
                sapBaseResponseDTO.setUuid(data.get(0).getUuid());
            } catch (Exception e) {
                sapBaseResponseDTO.setResult(DockDataStatus.FAILURE.getCode());
                sapBaseResponseDTO.setUuid(data.get(0).getUuid());
                throw new JeecgBootException("外购采购订单主数据发货出错", e);
            } finally {
                list.add(sapBaseResponseDTO);
            }
        }
        return list;
    }

    @Override
    public SapInterfaceTypeEnum type() {
        return SapInterfaceTypeEnum.OUT_PURCHASE_ORDER_MAIN_DATA;
    }

}
